
--local tArgs = { ... }
rednet.open("left") -- Open wireless modem on left hand side
vdu = peripheral.wrap("right") -- Wrap console on right hand side

term.clear()
vdu.setTextScale(0.5)

local isColour = term.isColor()

term.setCursorPos(1,1)
gScreenWidth, gScreenHeight = term.getSize()
print("Screen is w"..gScreenWidth.." x h"..gScreenHeight)

-- In order to handle multiple client turtles, we set up a table that will hold them all.
-- Key   : the client ID ('senderId' in rednet terms)
-- Value : another table, itself made up of
--				 [time] - time of last update (as per os.clock() call)
--				 [distance] - last recorded distance between the client rednet modem and this computer
--				 [range] - the number of moves it can do without refuelling
--				 [fuel] - the amount of fuel in slot 1 of the turtle inventory
--				 [status] - turtle status, one of : inactive,active,blocked,fuel,full,finished
--				 [x] - last reported X position (relative to home which is 0,0,0)
--				 [y] - last reported Y position (")
--				 [z] - last reported Z position (")
--				 [inventory] - last reported count of items in inventory
--				 [freeslots] - last reported number of free slots in turtle (ie. empty slots, excluding the fuel slot which is slot 1)
--				 [lastmsg] - last message received from the client (text message)
clients = {}
selectedTurtle = 0 -- Which turtle to monitor (if more than one are being monitored)

-- FUNCTIONS

-- Function to monitor keypresses and exit if Q is pressed
function keyPressed()
	while true do
		local num,key = os.pullEvent("char")
		if key == "q" then -- q pressed
			break
		elseif key == "n" then
			local nextTurtle = 0
			for k,v in pairs(clients) do
				if k==selectedTurtle then
					nextTurtle=true
				elseif nextTurtle==true then
					selectedTurtle=k
				end
			end
		elseif key == "p" then
			local prevTurtle = 0
			for k,v in pairs(clients) do
				if (prevTurtle==0 and type(k)~="nil") then
					prevTurtle = k
				elseif type(k)~="nil" and selectedTurtle==k then
					selectedTurtle=prevTurtle
				end
			end
		end
	end
end

-- Prints at a given position on the screen, but will optionally not print past a truncate limit
-- (effectively trims the string to a given length before printing). If truncate is ommitted, the
-- function will honour the screen width set by gScreenWidth
function printAt(text,x,y,truncate)
	vdu.setCursorPos(x,y)
	if type(truncate)=="nil" then
		truncate=gScreenWidth-x
	end
	local toprint = string.sub(tostring(text),1,truncate)
	vdu.write(toprint..string.rep(" ",gScreenWidth-truncate-x))
end

function printCentered(text,y)
	local toprint = tostring(text)
	vdu.setCursorPos(gScreenWidth/2 - string.len(toprint)/2, y)
	vdu.write(tostring(toprint))
end

function initDisplay()
-- VDU graphics size is (1..24) on x axis
--                      (1..57) on y axis

-- Set up display
	vdu.clear()
	printCentered("TurtleMonitor",1)
	printAt("Turtle   :",1,3)
	printAt("Updated  :",1,4)
	printAt("Distance :",1,5)
	printAt("Range    :",1,6)
	printAt("Fuel     :",1,7)
	printAt("Status   :",1,8)
	printAt("Co-ords  :",1,9)
	printAt("Items    :",1,10)
	printAt("Free Slot:",1,11)
	printAt("Last received message...",1,12)
	printAt("[q]-Quit [n]-Next Turtle [p]-Previous turtle",1,24)
		
	--paintutils.drawLine(1,1,1,24,colors.red)
	--paintutils.drawLine(57,1,57,24,colors.lime)
end

function monitorRednet()
	while true do
		local turtleId,message,distance = rednet.receive()
		-- Reminder of message format (comma-separated)
		-- LOGGERAPI,<turtle ID>,<turtle fuel range>,<turtle fuel stock in inv>,<status>,<x>,<y>,<z>,<total # items in inv>,<free slots>,[text message - may include commas]
		tResponse=textutils.unserialize(message)
		if type(tResponse)=="table" and table.remove(tResponse,1)=="LOGGERAPI" then
			clients[turtleId]=tResponse
			clients[turtleId].time = os.clock()
			clients[turtleId].distance = distance
			clients[turtleId].id = turtleId
			-- If this is the first turtle to report in, set it as the one to monitor/display
			if selectedTurtle==0 then selectedTurtle=turtleId end
		else
			print("Received non-loggerapi message; will ignore")
			print(">>"..message)
		end
	end
end

function updateVDU()
	while true do
		if selectedTurtle>0 then
			printAt(clients[selectedTurtle].id,12,3)
			printAt(clients[selectedTurtle].time,12,4,10)
			printAt(math.ceil(clients[selectedTurtle].distance),12,5,8)
			printAt(math.floor(clients[selectedTurtle].range),12,6,6)
			printAt(clients[selectedTurtle].fuel,12,7,6)
			if isColour and (clients[selectedTurtle].status=="active" or clients[selectedTurtle].status=="finished") then
				term.setTextColor(colors.green)
			elseif isColour and (clients[selectedTurtle].status=="blocked" or clients[selectedTurtle].status=="inactive") then
				term.setTextColor(colors.red)
			else
				term.setTextColor(colors.orange)
			end
			printAt(clients[selectedTurtle].status,12,8,10)
			if isColour then
				term.setTextColor(colors.white)
			end
			printAt(clients[selectedTurtle].x..","..clients[selectedTurtle].y..","..clients[selectedTurtle].z,12,9,10)
			printAt(clients[selectedTurtle].inventory,12,10,3)
			printAt(clients[selectedTurtle].freeslots,12,11,2)
			if (type(clients[selectedTurtle].msg)=="string" and string.len(clients[selectedTurtle].msg)>0) then
				printAt(clients[selectedTurtle].msg,2,13)
			end
		end
		sleep(20)
	end
end

-------------------------
--       MAIN LOOP     --
-------------------------

print("Master console ID is "..os.computerID())
initDisplay()

parallel.waitForAny(monitorRednet, updateVDU, keyPressed)

rednet.close("left")

